#include "v4l2.h"

#include <signal.h>
#include <stdio.h>
#include "lcd.h"
#include "camera.h"
#include <stdlib.h>
// #include "myjpeg.h"

int stop = 0;
int cut = -1;
//信号处理函数：当ctrl+c时，退出
void handle_signal(int signo)
{
	if (signo == SIGINT)
	{
		stop = 1;
	}
}

void YUV422toRGB888(int width, int height, unsigned char *src, unsigned char *dst)
{
	int line, column;
	unsigned char *py, *pu, *pv;
	unsigned char *tmp = dst;

	py = src;
	pu = src + 1;
	pv = src + 3;
	#define CLIP(x) ((x) >= 0xFF ? 0xFF : ((x) <= 0x00 ? 0x00 : (x)))
	for (line = 0; line < height; ++line)
	{
		for (column = 0; column < width; ++column)
		{
			*tmp++ = CLIP((int)*py + ((int)*pu - 128) + ((103 * ((int)*pu - 128)) >> 8));
			*tmp++ = CLIP((int)*py - (88 * ((int)*pv - 128) >> 8) - ((183 * ((int)*pu - 128)) >> 8));
			*tmp++ = CLIP((int)*py + ((int)*pv - 128) + ((198 * ((int)*pv - 128)) >> 8));
			// increase py every time
			py += 2;
			// increase pu,pv every second time
			if ((column & 1) == 1)
			{
				pu += 4;
				pv += 4;
			}
		} //end for col
	}	  //end for line
}
// void *camera(void *arg) {
//     // 初始化
//     signal(SIGINT, handle_signal);
//     v4l2_init();
//     lcd_init();

//     // 读取一帧-格式转换-显示到本地LCD-入队
//     while (stop == 0) {
//         struct Frame frame = v4l2_get_frame();
//         char rgb888[frame.width * frame.height * 3];
//         // yuv直接转rgb
//         YUV422toRGB888(frame.width, frame.height, frame.addr, rgb888);
//         printf("fw: %d, fh: %d\n", frame.width, frame.height);

//         // 显示rgb图像到lcd屏幕
//         lcd_draw_rgb888(rgb888, frame.width, frame.height, 0, 0);
//         // 把帧缓冲区加入采集队列
//         v4l2_enqueue(frame.index);
//     }

//     // 释放资源
//     v4l2_uninit();
//     lcd_uninit();
    
//     return NULL;
// }

void *camera(void *arg)
{
    // 初始化
    signal(SIGINT, handle_signal);
    v4l2_init();
    lcd_init();

    // 读取一帧-格式转换-显示到本地LCD-入队
    while (stop == 0)
    {

        struct Frame frame = v4l2_get_frame();
        char rgb888[frame.width * frame.height * 3];
        // yuv直接转rgb
        YUV422toRGB888(frame.width, frame.height, frame.addr, rgb888);
        printf("fw: %d, fh: %d\n", frame.width, frame.height);

        // 显示rgb图像到lcd屏幕
        lcd_draw_rgb888(rgb888, frame.width, frame.height, 0, 0);
        // 把帧缓冲区加入采集队列
        v4l2_enqueue(frame.index);

        if (cut == 0)
        {
            int nums = numsofAlbum(); // 获取图库中的图片数量
            char filename[50];        // 分配足够空间的数组来保存文件名
            char number[10];          // 保存数字部分的字符串

            // 将数字转换为字符串
            snprintf(number, sizeof(number), "%d", nums + 1);

            // 生成完整的文件名
            snprintf(filename, sizeof(filename), "img/%s.bmp", number);

            // 调用write_bmp函数保存图像
            write_bmp(filename, rgb888, 640, 480);

            // 标记已截图
            cut = -1;
        }
    }

    // 释放资源
    v4l2_uninit();
    lcd_uninit();

    return NULL;
}

char *lastCut()
{
    int nums = numsofAlbum(); // 获取图库中的图片数量
    char *filename = malloc(50 * sizeof(char));  // 动态分配空间来保存文件名
    if (filename == NULL) {
        perror("malloc failed");
        exit(EXIT_FAILURE);
    }
    char number[10];          // 保存数字部分的字符串

    // 将数字转换为字符串
    snprintf(number, sizeof(number), "%d", nums);

    // 生成完整的文件名
    snprintf(filename, 50, "img/%s.bmp", number); // 这里用 50 来限制写入长度
    return filename; // 返回最后一张截图的名字
}